#ifndef MESSAGESHOWAREA_H
#define MESSAGESHOWAREA_H

#include <QLabel>
#include <QPushButton>
#include <QResizeEvent>
#include <QScrollArea>
#include <QVBoxLayout>
#include "Model/Data.h"
#include "Style.h"

////////////////////////////////////////////
/// 右侧的消息展示区域
////////////////////////////////////////////
class MessageShowArea : public QScrollArea
{
    Q_OBJECT
public:
    MessageShowArea();
    /* 尾插消息 */
    void add_message(const model::Message& message, bool is_left);
    /* 头插消息 */
    void insert_message(const model::Message& message, bool is_left);
    /* 删除消息 */
    void clear_message();
    /* 将滚动条移动到最下面 */
    void scroll_to_bottom();
protected:
    void wheelEvent(QWheelEvent* event) override;
private:
    const QString SCROLL_STYLE = get_scroll_area_style();
    QWidget*      container;
    QVBoxLayout*  layout;
    bool          auto_scroll_enabled = true;  // 当前是否启动自动滚动
};
////////////////////////////////////////////
/// 用户发的每一条消息，包含自己发的和别人发的,
/// 包含用户的用户名和发送时间
////////////////////////////////////////////
class MessageItem : public QWidget
{
    Q_OBJECT
public:
    MessageItem(bool is_left);
    /* 创建消息的的工厂方法 */
    static MessageItem* make_message_item(const model::Message& message, bool is_left);
private:
    /* 工厂方法的实现 */
    static QWidget* make_text_message_item(const QByteArray& content, bool is_left);
    static QWidget* make_image_message_item(const QString& file_id, const QByteArray& content, bool is_left);
    static QWidget* make_file_message_item(const QString& file_id, const QByteArray& content, const QString& file_name, bool is_left);
    static QWidget* make_speech_message_item(const QString& file_id, const QByteArray& content, bool is_left);
private:
    bool is_left;  // true表示是别人发的消息
};
////////////////////////////////////////////
/// 显示到界面上的消息的实现, 包含纯色背景和label
////////////////////////////////////////////
class MessageContentLabel : public QWidget
{
public:
    MessageContentLabel(const QString& text, bool is_left);
protected:
    void paintEvent(QPaintEvent* event) override;
private:
    QLabel* label;  // 显示的文本消息
    bool    is_left;
};
////////////////////////////////////////////
/// 显示到界面上的图片消息的实现
////////////////////////////////////////////
class MessageImageLabel : public QWidget
{
public:
    MessageImageLabel(const QString& file_id, const QByteArray& data, bool is_left);
protected:
    void paintEvent(QPaintEvent* event) override;
private:
    void update_content(const QString& file_id, const QByteArray& file_content);
private:
    QPushButton* image_button;         // 用于显示图片
    QString      file_id;              // 文件ID
    QByteArray   data;                 // 图片数据
    bool         is_left;              // true表示是别人发的消息
    QPixmap      cachedPixmap;         // 用于缓存已经加载的图片
    bool         imageLoaded = false;  // 图片是否已经加载
};
////////////////////////////////////////////
/// 显示到界面上的文件消息的实现
////////////////////////////////////////////
class MessageFileLabel : public QWidget
{
public:
    MessageFileLabel(const QString& file_id, const QByteArray& content, const QString& file_name, bool is_left);
protected:
    void paintEvent(QPaintEvent* event) override;
    void mousePressEvent(QMouseEvent* event) override;
private:
    void update_content(const QString& file_id, const QByteArray& file_content);
private:
    QLabel*    label;      // 显示的文件消息, 只显示文件名
    QString    file_id;    // 文件ID
    QString    file_name;  // 文件名
    bool       is_left;
    QByteArray data;       // 文件数据
};

////////////////////////////////////////////
/// 显示到界面上的语音消息的实现
////////////////////////////////////////////
class MessageSpeechLabel : public QWidget
{
public:
    MessageSpeechLabel(const QString& file_id, const QByteArray& content, bool is_left);
protected:
    void paintEvent(QPaintEvent* event) override;
    void mousePressEvent(QMouseEvent* event) override;
    void contextMenuEvent(QContextMenuEvent* event) override;
private:
    void update_content(const QString& file_id, const QByteArray& speech_content);
    void speech_recognition();
private:
    QLabel*    label;    // 显示的文件消息, 只显示[语音]
    QString    file_id;  // 文件ID
    bool       is_left;
    QByteArray data;     // 语音数据
};
#endif  // MESSAGESHOWAREA_H
